#include "xmlcapture.h" 
#include "system.h"
#include "winassert.h"
using win::ChildWindow;
using win::Window;
using std::runtime_error;
using doc::Attribute;
using doc::DocNode;

namespace {
}
namespace view
{
    using win::EditBox;
    using win::ComboBox;
    using doc::Property;
	using doc::ListProperty;
	using win::TextControl;
	
	using win::Window;
	using design::pointer_list;

	HWND s_dialogHandle = 0;
	LRESULT CALLBACK TuxCapture::ChildWndProc(HWND hwnd, UINT msg,
 								  WPARAM wParam, LPARAM lParam)
	{
		static Window w;
		static TuxCapture* view = 0;
		w.Attach(hwnd);
		return DefWindowProc( hwnd,msg,wParam,lParam );
	}

	HWND TuxCapture::GetDialogHandle()
    {
        return s_dialogHandle;
    }
    

 	void TuxCapture::AdjustLayout(int x, int y, int w, int h)
 	{
		MoveWH(x,y,w,h);
	    _box.MoveWH(0,0,w,h);
 	}

	void TuxCapture::ShowAttributes()
	{
	  	CompositeEditBox::ItemPtrBasket items;
		if (TuxDocument::Instance().IsNodeSelected())
		{
			DocNode * node = TuxDocument::Instance().FocusNode();
			// add the attributes to the list
			const pointer_list<Attribute> & attribs = node->Attribs();
			pointer_list<Attribute>::const_iterator it = attribs.begin();
	      	Rect r(10,10,50,10);
	      	int ctl_index = 0;
	      	while (it != attribs.end())
	      	{
                 Attribute* a = *it;
                 if (a->Type().IsReadOnly() == false)
                 {
	                 // create an edit control
	                 TextControl* w = 0;
	                 switch (a->Type().Type())
	                 {
	                 	case Property::pt_boolean:
	                 		{
	                 			ComboBox * b = new ComboBox();
		                 		b->Create(_box,ctl_index++);
	   		              		b->Add("yes");
	   		              		b->Add("no");
	   		              		b->SelectString(a->Value().c_str());
	        	         		w = b;
	           		      	}
	                 		break;
	             		 case Property::pt_list:
	                 		{
			                    const ListProperty &p =
			                    	static_cast<const ListProperty&> (a->Type());
			                    const list<string> & items = p.Items(*node);
			                    const ComboBox::eBoxType boxType =
			                    	p.IsStrict()?
	                       					ComboBox::btDropDownList
	                            		:	ComboBox::btDropDown;

	                 			ComboBox * b = new ComboBox();
		                 		b->Create(_box,ctl_index++,boxType);
		                 		list<string>::const_iterator it;
		                 		it = items.begin();
		                 		while (it != items.end())
		                 		{
		                 			b->Add(it->c_str());
		                 			it++;
		                 		}
		                 		if (p.IsStrict())
		   		              		b->SelectString(a->Value().c_str());
		   		              	else
						      	     b->SetText(a->Value().c_str());
	        	         		w = b;
	                 		}
	                 		break;
	                	 default:
	                	 	{
	      	 		      	     EditBox * b = new EditBox();
					      	     b->Create(_box,ctl_index++,r);
					      	     b->SetText(a->Value().c_str());
					      	     w = b;
	      	     			}
	                 }
	                 if (w)
	                 {
	                 	w->SetPointer(a);
			      	    items.push_back( new CompositeEditBox::
	             					Item(a->Type().Name(), w,
		                            a->Type().Hint()));
                     }
				}
                it++;
	      	}
		}
      	_box.SetItems(items);
	}
	
	void TuxCapture::SaveAttributes()
	{
		DocNode * node = TuxDocument::Instance().FocusNode();
		if (node)
		{
			// save attributes back to document
			typedef CompositeEditBox::ItemPtrBasket basket_t;
			typedef CompositeEditBox::Item item_t;
			basket_t::const_iterator it = _box.Items().begin();
			while (it != _box.Items().end())
			{
                item_t* i = *it;
                TextControl * b = static_cast<TextControl *> (i->Ctl());
                if (b->IsModified())
                {
	                Attribute* a = static_cast<Attribute*> (b->GetPointer());
					string value = b->GetText();
	                a->SetValue(value);
                }   
	            it++;
			}
		}
	}
	
	void TuxCapture::Update(Observable *, int aspect)
	{
		switch (aspect)
		{
			case TuxDocument::ASPECT_FOCUS_OPEN:
				ShowAttributes();
				break;
			case TuxDocument::ASPECT_FOCUS_CLOSE:
				_box.ClearItems();
				break;
			case TuxDocument::ASPECT_FOCUS_SAVE:
				SaveAttributes();
				break;
		}
		
	}

    void TuxCapture::Create(const Window &parent,
                             const int child_index)
    {
         _child_index = child_index;
         const HWND parent_handle = parent.GetHandle();
         const HINSTANCE instance_handle = reinterpret_cast<HINSTANCE>
             							(GetWindowLong(parent_handle,GWL_HINSTANCE));
    	 // Register editor window
    	 static const char * CAPTURE_CLASS = "xml_capture";
    
    	 WNDCLASS wc;
    	 ZeroMemory(&wc,sizeof(wc));
    	 wc.style = 0; 
    	 wc.hInstance = instance_handle;
    	 wc.hbrBackground = (HBRUSH) NULL;
//    	 wc.hCursor = LoadCursor (NULL, IDC_ARROW);
		 wc.lpfnWndProc = TuxCapture::ChildWndProc;
    	 wc.lpszClassName = CAPTURE_CLASS;
    	 if (!RegisterClass(&wc))
    	 	throw runtime_error("Register class failed");
    
     	_hwnd = CreateWindow( CAPTURE_CLASS,NULL,
      							WS_CHILD | WS_VISIBLE | WS_BORDER,
      							0,0,0,0,
             					parent_handle,
             					reinterpret_cast<HMENU> (_child_index),
      							instance_handle,
      							static_cast<LPVOID> (this));
    	if (_hwnd == NULL)
    		throw runtime_error("Create window failed");
    	SetPointer(this);	
      	_box.Create(*this,1);	
      	s_dialogHandle = _box.GetHandle();
      	TuxDocument::Instance().Attach(this);
    }
}

